import { ref, onUnmounted } from 'vue';

/**
 * 防抖 Hook
 * @param value 需要防抖的值
 * @param delay 延迟时间（毫秒）
 * @returns 防抖后的值
 */
export function useDebounce<T>(value: T, delay: number) {
  const debouncedValue = ref(value) as { value: T };
  let timeoutId: number | null = null;

  const updateDebouncedValue = (newValue: T) => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    
    timeoutId = window.setTimeout(() => {
      debouncedValue.value = newValue;
    }, delay);
  };

  // 监听原始值变化
  updateDebouncedValue(value);

  onUnmounted(() => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
  });

  return debouncedValue;
}

/**
 * 防抖函数 Hook
 * @param fn 需要防抖的函数
 * @param delay 延迟时间（毫秒）
 * @returns 防抖后的函数
 */
export function useDebounceFn<T extends(..._args: any[]) => any>(
  fn: T,
  delay: number
) {
  let timeoutId: number | null = null;

  const debouncedFn = function(this: any,...args: Parameters<T>)  {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    
    timeoutId = window.setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };

  // 取消延迟执行
  const cancel = () => {
    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = null;
    }
  };

  onUnmounted(() => {
    cancel();
  });

  return {
    run: debouncedFn,
    cancel
  };
}